package org.xiaojl.utils;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpsClientHelp {
	public static Logger log = LoggerFactory.getLogger(HttpClientHelp.class);
	// 创建默认的httpClient客户端
	private HttpClient httpClient = null;
	// post模式
	private HttpPost httpPost = null;
	// 执行请求，获取服务器响应
	private HttpResponse response = null;
	// 请求的实体
	private HttpEntity entity = null;

	private static X509TrustManager trustManager = new X509TrustManager() {
		public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
		}

		public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
		}

		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}

	};

	public static HttpClient getInstance() throws KeyManagementException, NoSuchAlgorithmException {
		HttpClient client = new DefaultHttpClient();
		SSLContext ctx = SSLContext.getInstance("SSL");
		// SSLContext ctx = SSLContext.getInstance("TLS");
		ctx.init(null, new TrustManager[] { trustManager }, null);
		SSLSocketFactory ssf = new SSLSocketFactory(ctx);
		// 忽略掉HostName的比较，否则访问部分地址可能会报异常
		ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
		ClientConnectionManager ccm = client.getConnectionManager();
		SchemeRegistry sr = ccm.getSchemeRegistry();
		sr.register(new Scheme("https", 443, ssf));
		client = new DefaultHttpClient(ccm, client.getParams());
		return client;
	}

	/**
	 * 释放资源
	 * 
	 * @param httpGet
	 * @param httpPost
	 * @param httpClient
	 */
	public void releaseSource(HttpGet httpGet, HttpPost httpPost, HttpClient httpClient) {
		if (httpGet != null) {
			httpGet.abort();
		}
		if (httpPost != null) {
			httpPost.abort();
		}
		if (httpClient != null) {
			httpClient.getConnectionManager().shutdown();
		}
	}

	/**
	 * Post方式提交并且返回Entity字符串
	 * 
	 * @param url
	 *            提交的url
	 * @param client
	 *            HttpClient
	 * @param post
	 *            HttpPost
	 * @param params
	 *            队列参数
	 * @param urlEncoded
	 *            url编码
	 * @return
	 * @throws KeyManagementException 
	 * @throws ClientProtocolException 
	 */
	public String byPostMethodToHttpEntity(String url, List<NameValuePair> params, String urlEncoded) throws Exception {
		StringBuffer buff = new StringBuffer();
		try {
			httpClient = HttpsClientHelp.getInstance();
			
			// 创建一个HttpGet请求，作为目标地址。
			httpPost = new HttpPost(url);
			if (params != null) {
				// 格式化参数列表并提交
				UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(params, urlEncoded);
				httpPost.setEntity(uefEntity);
			}
			response = httpClient.execute(httpPost);
			if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
				entity = response.getEntity();
				buff.append(EntityUtils.toString(entity));
			}
			System.out.println("请求地址: " + httpPost.getURI()); 
            System.out.println("响应状态: " + response.getStatusLine()); 
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常ClientProtocolException：", e);
			throw e;
		} catch (IOException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常IOException：", e);
			throw e;
		} catch (KeyManagementException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常KeyManagementException：", e);
			throw e;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常NoSuchAlgorithmException：", e);
			throw e;
		} finally {
			releaseSource(null, httpPost, httpClient);
		}
		return buff.toString();
	}
	
	
	/**
	 * 微信接口请求
	 * @param url
	 * @param params
	 * @param urlEncoded
	 * @return
	 * @throws Exception
	 */
	public String byWxPostMethodToHttpEntity(String url, List<NameValuePair> params, String urlEncoded) throws Exception {
		StringBuffer buff = new StringBuffer();
		try {
			httpClient = HttpsClientHelp.getInstance();
			
			// 创建一个HttpGet请求，作为目标地址。
			httpPost = new HttpPost(url);
			if (params != null) {
				// 格式化参数列表并提交
				UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(params, urlEncoded);
				httpPost.setEntity(uefEntity);
			}
			response = httpClient.execute(httpPost);
			if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
				entity = response.getEntity();
				buff.append(EntityUtils.toString(entity, urlEncoded));
			}
			System.out.println("请求地址: " + httpPost.getURI()); 
            System.out.println("响应状态: " + response.getStatusLine()); 
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常ClientProtocolException：", e);
			throw e;
		} catch (IOException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常IOException：", e);
			throw e;
		} catch (KeyManagementException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常KeyManagementException：", e);
			throw e;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			log.error("HttpsClientHelp出现异常NoSuchAlgorithmException：", e);
			throw e;
		} finally {
			releaseSource(null, httpPost, httpClient);
		}
		return buff.toString();
	}

	public static void main(String[] args) {

	}

}
